﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////

#pragma once
#include "YccModelBase.h"
#include "ElementId.h"
#include "UniIdentity.h"
#include "IElementBasicInformation.h"
#include "GapIExtraDataComponent.h"

namespace gap
{
    // gap中所有对象的根积基类
    class YCC_MODEL_BASE_EXPORT IEntity
    {
        DEFINE_CAST_BASE(IEntity)
    public:
        virtual ~IEntity();

        // Note : 在接口中增加新的方法时，下面的宏中也需相应增加
    public:
        // Basic Methods
        virtual gcmp::ElementId GetElementId() const = 0;
        virtual const gcmp::UniIdentity& GetCategoryUid() const = 0;
        virtual const std::wstring& GetName() const = 0;

        // Host Elements Methods
        virtual std::vector<gcmp::ElementId> GetHostElementIds() const = 0;

        /// \brief 获得扩展数据组件接口
        /// \return const IExtraDataComponent * 扩展数据组件接口
        virtual const gap::IExtraDataComponent* GetExtraDataComponent() const;

        /// \brief 获得扩展数据组件接口
        /// \return IExtraDataComponent * 扩展数据组件接口
        virtual gap::IExtraDataComponent* GetExtraDataComponentFW();
    };
}

// IEntity纯虚函数的统一声明
#define DECLARE_GAP_ENTITY_BASIC_METHODS \
    virtual gcmp::ElementId GetElementId() const override; \
    virtual const gcmp::UniIdentity& GetCategoryUid() const override;   \
    virtual const std::wstring& GetName() const override;

#define DECLARE_GAP_ENTITY_GET_HOST_ELEMENTS_METHOD \
    virtual std::vector<gcmp::ElementId> GetHostElementIds() const;

#define DECLARE_GAP_ENTITY_METHODS_WITHOUT_HOSTS \
    DECLARE_GAP_ENTITY_BASIC_METHODS \
    virtual const gap::IExtraDataComponent* GetExtraDataComponent() const override; \
    virtual gap::IExtraDataComponent* GetExtraDataComponentFW() override;

#define DECLARE_GAP_ENTITY_METHODS_WITHOUT_EXTRA_DATA \
    DECLARE_GAP_ENTITY_METHODS_WITHOUT_HOSTS \
    DECLARE_GAP_ENTITY_GET_HOST_ELEMENTS_METHOD

#define DECLARE_GAP_ENTITY_METHODS \
    DECLARE_GAP_ENTITY_METHODS_WITHOUT_HOSTS \
    DECLARE_GAP_ENTITY_GET_HOST_ELEMENTS_METHOD


// IEntity纯虚函数的统一实现
#define DEFINE_GAP_ENTITY_BASIC_METHODS(CLASS_NAME) \
    gcmp::ElementId CLASS_NAME::GetElementId() const \
    { \
        return (GetOwnerElement() != nullptr) ? GetOwnerElement()->GetElementId() : gcmp::ElementId::InvalidID; \
    } \
    const gcmp::UniIdentity& CLASS_NAME::GetCategoryUid() const \
    { \
        return (GetOwnerElement() != nullptr) ? \
        GetOwnerElement()->GetBasicInformation()->GetCategoryUid() : gcmp::UniIdentity::InvalidUid; \
    } \
    const std::wstring& CLASS_NAME::GetName() const \
    { \
        static const std::wstring emptyString = L""; \
        return (GetOwnerElement() != nullptr) ? GetOwnerElement()->GetBasicInformation()->GetName() : emptyString; \
    }

#define DEFINE_GAP_ENTITY_GET_HOST_ELEMENTS_METHOD(CLASS_NAME) \
    std::vector<gcmp::ElementId> CLASS_NAME::GetHostElementIds() const \
    { \
        const gcmp::IElement* pOwnerElement = GetOwnerElement(); \
        if (pOwnerElement && pOwnerElement->GetHostElementId().IsValid()) \
            { return { pOwnerElement->GetHostElementId() }; } \
        return {}; \
    }

#define DEFINE_GAP_ENTITY_METHODS_WITHOUT_HOSTS(CLASS_NAME) \
    DEFINE_GAP_ENTITY_BASIC_METHODS(CLASS_NAME) \
    const gap::IExtraDataComponent* CLASS_NAME::GetExtraDataComponent() const \
    { \
        return GetExtraDataComponent__().get(); \
    } \
    gap::IExtraDataComponent* CLASS_NAME::GetExtraDataComponentFW() \
    { \
        return GetExtraDataComponentFW__().get(); \
    }

#define DEFINE_GAP_ENTITY_METHODS_WITHOUT_EXTRA_DATA(CLASS_NAME) \
    DEFINE_GAP_ENTITY_BASIC_METHODS(CLASS_NAME) \
    DEFINE_GAP_ENTITY_GET_HOST_ELEMENTS_METHOD(CLASS_NAME) \
    const gap::IExtraDataComponent* CLASS_NAME::GetExtraDataComponent() const \
    { \
        return nullptr; \
    } \
    gap::IExtraDataComponent* CLASS_NAME::GetExtraDataComponentFW() \
    { \
        return nullptr; \
    }

#define DEFINE_GAP_ENTITY_METHODS(CLASS_NAME) \
    DEFINE_GAP_ENTITY_METHODS_WITHOUT_HOSTS(CLASS_NAME) \
    DEFINE_GAP_ENTITY_GET_HOST_ELEMENTS_METHOD(CLASS_NAME)
